package com.rulestech.framework.unittest;

import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import com.rulestech.engine.DecisionEngine;
import com.rulestech.engine.EngineContext;
import com.rulestech.engine.EngineLogger;
import com.rulestech.engine.EngineResult;


/**
 *  This base class setup the foundation for the data driven unit test for the DecisionEngine. 
 *  
 *  The idea is that the sub class only needs to specify the actual engine, the actual output reference and the actual logger and leave everything else to the base class.
 * 
 * 
 * @author seanxsu
 *
 */
@RunWith(Parameterized.class)
public abstract class DataDrivenDecisionEngineBaseTest extends DataDrivenBaseTest {

	/**
	 * The actual implementation of this method calculates the output based on the input and the decision engine to be determined.
	 * @param input the input to be used.
	 * @return output calculated by the decision engine
	 */
	@Override
	protected Object computeActualResult(Object input) throws Exception{
		EngineResult result = buildDecisionEngineOutputReference();

		//update the actual output 
		getDecisionEngine().invoke((EngineContext)input, result, getDecisionEngineLogger());
		
		return result;
	}
	
	/**
	 * The users of the framework must implement this method to retrieve the reference to be passed to the decision engine. 
	 * 
	 * @return the Engine result object.
	 * @throws Exception
	 */
	protected abstract EngineResult buildDecisionEngineOutputReference()  throws Exception;
	
	/**
	 * The users of the framework must implement this method to retrieve the decision engine to be used when calculating the actual result.
	 * @return
	 */
	protected abstract DecisionEngine getDecisionEngine();
	
	/**
	 * The users of the framework must implement this method to retrieve the logger to be used by decision engine
	 * @return
	 */
	protected abstract EngineLogger getDecisionEngineLogger();

	public DataDrivenDecisionEngineBaseTest(Object input, Object output) throws Exception {
		super(input, output);
	}
	
}
